package com.geline.mybatisplus.handler.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.geline.cloud.core.BaseSessionService;
import com.geline.mybatisplus.handler.MetaEntityHandler;
import org.springframework.cglib.beans.BeanMap;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Date;

public class DefaultMetaEntityHandler implements MetaEntityHandler {

    private BaseSessionService sessionService;

    public DefaultMetaEntityHandler(BaseSessionService sessionService){
        this.sessionService = sessionService;
    }

    @Override
    public void insertFill(Object entity) {
        Field[] fields = entity.getClass().getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            if (fieldName.equals("id")) {
                String idValue = generateIdValue(entity);
                if(idValue != null){
                    if(field.getType() == Long.class){
                        BeanMap.create(entity).put("id", Long.valueOf(idValue));
                    }else {
                        BeanMap.create(entity).put("id", idValue);
                    }
                }
            }else if (fieldName.equals("createTime")) {
                BeanMap.create(entity).put("createTime", new Date());
            }else if (fieldName.equals("updateTime")) {
                BeanMap.create(entity).put("updateTime", new Date());
            }else if (fieldName.equals("createBy")) {
                Serializable userId = sessionService.getUserId();
                BeanMap.create(entity).put("createBy", userId);
            }else if (fieldName.equals("updateBy")) {
                Serializable userId = sessionService.getUserId();
                BeanMap.create(entity).put("updateBy", userId);
            }
        }
    }

    @Override
    public void updateFill(Object entity) {
        Field[] fields = entity.getClass().getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            if (fieldName.equals("updateTime")) {
                BeanMap.create(entity).put("updateTime", new Date());
            }else if (fieldName.equals("updateBy")) {
                Serializable userId = sessionService.getUserId();
                BeanMap.create(entity).put("updateBy", userId);
            }
        }
    }

    private String generateIdValue(Object entity) {
        Field idField = ClassUtil.getDeclaredField(entity.getClass(), "id");
        TableId tableId = idField.getAnnotation(TableId.class);
        IdType idType = tableId.type();
        if(idType== IdType.AUTO || idType== IdType.NONE){
            return null;
        }else if(idType==IdType.ASSIGN_ID){
            Snowflake snowflake = IdUtil.getSnowflake();
            return String.valueOf(snowflake.nextId());
        }else if(idType==IdType.ASSIGN_UUID){
            return IdUtil.fastSimpleUUID();
        }else {
            throw new RuntimeException("can not handle IdType : "+idType);
        }
    }
}
